package com.xc.sys.service;

import com.alibaba.druid.util.StringUtils;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.xc.common.object.PageInfo;
import com.xc.common.tool.BeanAid;
import com.xc.common.tool.Helper;
import com.xc.db.tables.BaseAttachment;
import com.xc.db.tables.records.BaseAttachmentRecord;
import com.xc.sys.entity.BaseAttachmentEntity;
import com.xc.sys.vo.BaseAttachmentVO;
import com.xc.sys.vo.SysUserVO;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.apache.commons.io.FileUtils;
import org.jooq.Condition;
import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SelectForUpdateStep;
import org.jooq.SelectSeekStepN;
import org.jooq.SortField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class BaseAttachmentService {
	@Value("${env.filedir}")
    private String filedir;
	@Autowired
	private DSLContext dsl;
	private BaseAttachment BASEATTACHMENT = BaseAttachment.BASE_ATTACHMENT.as("BASEATTACHMENT");

	public Result<Record> select(Condition whr, PageInfo<BaseAttachmentEntity> pageInfo, SortField<?>... orderby) {
		SelectSeekStepN<Record> seek = dsl.select().from(BASEATTACHMENT).where(whr).orderBy(orderby);
		Result<Record> result = null;
		if (pageInfo != null) {
			SelectForUpdateStep<Record> su = seek.limit(pageInfo.getLimit()).offset(pageInfo.getBeginNum());
			result = su.fetch();
		} else {
			result = seek.fetch();
		}
		if (pageInfo != null) {
			pageInfo.setResult(result);
			pageInfo.setList(result.into(BaseAttachmentEntity.class));
		}
		return result;
	}

	public List<BaseAttachmentEntity> select(Condition whr, SortField<?>... orderby) {
		Result<Record> result = dsl.select().from(BASEATTACHMENT).where(whr).orderBy(orderby).fetch();
		List<BaseAttachmentEntity> list = Lists.newArrayList();
		if (result.size() > 0) {
			list = result.into(BaseAttachmentEntity.class);
		}
		return list;
	}
	public List<BaseAttachmentVO> selectVo(Condition whr, SortField<?>... orderby) {
		Result<Record> result = dsl.select().from(BASEATTACHMENT).where(whr).orderBy(orderby).fetch();
		List<BaseAttachmentVO> list = Lists.newArrayList();
		if (result.size() > 0) {
			list = result.into(BaseAttachmentVO.class);
		}
		return list;
	}

	public Long count(Condition cond) {
		Long count = null;
		count = dsl.selectCount().from(BASEATTACHMENT).where(cond).fetchOneInto(Long.class);
		return count;
	}

	public Record getRecordById(String id) {
		Record record = dsl.select().from(BASEATTACHMENT).where(BASEATTACHMENT.ID.eq(id)).fetchOne();
		return record;
	}

	public BaseAttachmentEntity getEntityById(String id) {
		if(id==null) {
			return null;
		}
		BaseAttachmentEntity entity = getRecordById(id).into(BaseAttachmentEntity.class);
		return entity;
	}
	public BaseAttachmentVO getBoById(String id) {
		if(id==null) {
			return null;
		}
		Record r = getRecordById(id);
		BaseAttachmentVO entity = null;
		if(r!=null) {
			entity = r.into(BaseAttachmentVO.class);
			SysUserVO u = SysUserService.getFrameCaches(entity.getCreateUserId());
			if(u!=null) {
				entity.setCreateUserName(u.getName());
			}
		}
		return entity;
	}

	public String update(BaseAttachmentEntity entity) {
		BaseAttachmentRecord record = new BaseAttachmentRecord();
		record.from(entity);
		dsl.executeUpdate(record);
		BaseAttachmentService.cache.invalidate(entity.getId());
		return entity.getId();
	}

	public void update(Record record) {
		BaseAttachmentRecord sysNaviRecord = new BaseAttachmentRecord();
		sysNaviRecord.from(record);
		this.dsl.executeUpdate(sysNaviRecord);
	}

	public String insert(BaseAttachmentEntity entity) {
		BaseAttachmentRecord record = new BaseAttachmentRecord();
		if (StringUtils.isEmpty(entity.getId())) {
			String id = Helper.getSnowId() + "";
			entity.setId(id);
		}
		record.from(entity);
		this.dsl.executeInsert(record);
		return entity.getId();
	}

	public String save(BaseAttachmentEntity entity) {
		if (StringUtils.isEmpty(entity.getId())) {
			return insert(entity);
		}
		return update(entity);
	}

	public void deleteById(String id) {
		BaseAttachmentVO att = BaseAttachmentService.getFrameCaches(id);
		String filePath = filedir+File.separator+att.getFiledir()+att.getRepoName();
		File file = new File(filePath);
		try {
			if(file.exists()) {
				FileUtils.forceDelete(file);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		BaseAttachmentService.cache.invalidate(id);
		dsl.delete(BASEATTACHMENT).where(BASEATTACHMENT.ID.eq(id)).execute();
	}
	public static LoadingCache<String, Optional<BaseAttachmentVO>> cache = CacheBuilder.newBuilder()
			.maximumSize(50000).build(new CacheLoader<String, Optional<BaseAttachmentVO>>() {
				public Optional<BaseAttachmentVO> load(String id) {
					BaseAttachmentService service = BeanAid.getBean(BaseAttachmentService.class);
					BaseAttachmentVO user = service.getBoById(id);
					return Optional.fromNullable(user);
				}
			});

	public static BaseAttachmentVO getFrameCaches(String key) {
		if (key == null) {
			return null;
		}
		try {
			return cache.get(key).orNull();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		return null;
	}
}
